#ifndef _H_MAP
#define _H_MAP

#include <vector>
#include <pthread\cppthread.h>
#include "types.h"

#define CELL_NORMAL     0x00
#define CELL_OBSTACLE   0x01
#define CELL_OCCUPIED   0x02

#define DIR_UP      0
#define DIR_U_LEFT  1
#define DIR_D_LEFT  2
#define DIR_DOWN    3
#define DIR_D_RIGHT 4
#define DIR_U_RIGHT 5

using namespace std;

class mapObject;
class actor;
class dialog;
class gameEngine;

class mapCtr{

    protected:
        unsigned int size;
        int width;
        int height;

        vector<mapObject*> objects;
        vector<actor*> neutrals;
        vector<dialog*> dials;
        cell_t * data;

        vector<mapObject*>::iterator mainPtr;
        vector<actor*>::iterator neutralPtr;
        vector<dialog*>::iterator dialogPtr;

        gameEngine* parentEngine;

    public:
        cppthread_mutex_t neutralMutex;
        cppthread_mutex_t dialogMutex;

        mapCtr();
        ~mapCtr();

        int getWidth();
        int getHeight();

        void setParentEngine(gameEngine*);

        cell_t* getCell( int, int );
        cell_t* getCell( coord_t );
        bool isCellWalkable( int, int );
        bool isCellWalkable( coord_t );
        void setCell( cell_t, int, int );

        void addObject( mapObject* );
        void addDialog( dialog* );

        unsigned int countMain();
        void resetMP();
        mapObject* nextMP();
        mapObject* curMP();

        unsigned int countNeutral();
        void resetNP();
        actor* nextNP();
        actor* curNP();

        unsigned int countDials();
        void resetDP();
        dialog* nextDP();
        dialog* curDP();

        void execActions();

};

direc_t dir_opposite(direc_t);
direc_t dir_rotate(direc_t,int);
int getGridY(int y,int x);

bool getStatus(unsigned char,cell_t);
void setStatus(unsigned char,cell_t*,bool);

#endif
